//
// Created by Administrator on 2024/10/14.
//

#ifndef CNC_SIMULATION_NCMAIN_H
#define CNC_SIMULATION_NCMAIN_H



#include <QString>
#include <QDebug>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <QFile>
#include <QMessageBox>

//#include "../ToolParameterDialog/ToolParameterDialog.h"
#define START_CHARACTER '%'

using namespace std;
const QPointF MACHINE_ORIGIN(0.0, 0.0);  // 机器原点，X和Y坐标均为0.0
const double MAX_TRAVEL_SPEED = 2000.0;  // 最大游动速度，单位为 mm/min
const double MAX_FEED_RATE= 500.0; // 最大进给速度，单位可以根据需要调整，例如毫米每分钟
const double DEFAULT_VALUE = -9999.0; // 根据需要设置默认值




/**
 * NCCommand 类用于解析 G 和 M 代码命令。
 * 包含命令代码和各种参数（如位置、速度和刀具参数）。
 */
class NCCommand {

public:
    string code; // 命令代码


    // 位置和速度参数
    double X = DEFAULT_VALUE;
    double Y = DEFAULT_VALUE;
    double Z = DEFAULT_VALUE;
    double F = DEFAULT_VALUE;

    // 圆弧参数
    double I =DEFAULT_VALUE;
    double J =DEFAULT_VALUE;
    double R = 0.0;

    // 刀具参数
    QString Tool_num ; // 刀具编号

    double D = 0.0;   // 刀具直径
    double H = 0.0;   // 刀具长度

    // 主轴参数
    double S = 0.0;   // 主轴转速


    NCCommand(const string& command);// 构造函数
    ~NCCommand();  // 析构函数声明，缓存解析的上个点

    // 解析命令
    void parseCommand(const string& command);


private:
    // 解析 G 代码
    void parseCommand_G(const string& command);

    // 解析 M 代码
    void parseCommand_M(const string& command);
};

/**
 * ToolParameters 结构体用于存储刀具的相关信息。
 * 包含刀具 ID、刀具半径和刀具长度。
 */
struct ToolParameters {
    QString toolID;   // 刀具ID
    double radius;    // 刀具半径
    double length;    // 刀具长度
};
/**
 * GetToolData 类用于加载和获取刀具参数。
 * 通过刀具 ID 快速访问刀具的半径和长度信息。
 */
class GetToolData
{
public:
    void loadToolParameters(); // 加载刀具参数
    double getToolRadius(const QString &toolID); // 获取刀具半径
    double getToolLength(const QString &toolID); // 获取刀具长度
private:
    QMap<QString, ToolParameters> toolParametersMap; // 通过刀具ID快速访问刀具参数
};

/**
 * MachineState 枚举用于定义 CNC 机床的状态。
 * 机器的状态可以是以下几种：
 * - IDLE: 机器处于空闲状态，未执行任何操作。
 * - PROCESSING: 机器正在执行加工任务。
 * - PAUSED: 机器处于暂停状态，等待继续。
 * - RAPID_MOVE: 机器正在进行快速移动操作。
 */
enum MachineState{
    IDLE,       // 空闲状态
    PROCESSING, // 加工状态
    PAUSED,     // 暂停状态
    RAPID_MOVE  // 快速移动状态
};


/**
 * CNCStateMachine 类用于管理 CNC 机床的状态机。
 * 处理各种 NC 命令，并维护当前的机器状态。
 */
class CNCStateMachine:public QObject  {
Q_OBJECT
public:
    CNCStateMachine(); // 构造函数

    // 状态机事件处理
    void handleCommand(const NCCommand &command);

    // 获取当前状态
    string getState() const;
    //起点
    QPointF startPoint=MACHINE_ORIGIN;
    double startPoint_Z;
    //终点
    QPointF endPoint;
    double endPoint_Z;

    //圆心
    QPointF centerPoint;
    //速度
    double speed;
signals:
    void programExecutionFinished(); // 程序执行完的信号


private:
    // 刀具数据管理
    GetToolData toolData; // 添加 GetToolData 类的私有成员
    QString currentToolID;     // 当前刀具编号



    MachineState currentState; // 机器当前状态
    bool G90_OR_G91 = false;   // 使用 G90（绝对编程）或 G91（相对编程）
    //长度补偿
    bool G43_OR_G49 = false;//正向补偿
    bool G44_OR_G49 = false;//负向补偿

    //半径补偿
    bool G41_OR_G40 = false;//左侧刀具半径补偿
    bool G42_OR_G40 = false;//右侧刀具半径补偿


    double TOOL_H = 0;         // 刀具长度
    double TOOL_D = 0;         // 刀具直径


    // 读取数据
    void readDate(const NCCommand& cmd);
    //封装的一个直线通用移动函数
    void  moveToEndPoint(double speed, const NCCommand& cmd);
    //一个刀具偏移向量的计算函数
    QPointF calculateToolOffsetTargetPoint(const QPointF &Pointstart, const QPointF &Pointend, double R, bool G41_OR_G42);
    QPointF calculateToolOffsetTargetPointArc(const QPointF &point, const QPointF &pointCenter, double radius, bool isOuterCircle) ;
    // 各种命令的处理函数
    // 处理 G21 指令，设置单位为毫米
    void handleG21(const NCCommand &cmd);

// 处理 G90 指令，设置绝对坐标模式
    void handleG90(const NCCommand &cmd);

// 处理 G54 指令，选择工作坐标系 1
    void handleG54(const NCCommand &cmd);

// 处理 G00 指令，快速移动到指定坐标
    void handleG00(const NCCommand &cmd);

// 处理 G01 指令，线性插补移动到指定坐标
    void handleG01(const NCCommand &cmd);

// 处理 G02 指令，顺时针圆弧插补
    void handleG02(const NCCommand &cmd);

// 处理 G03 指令，逆时针圆弧插补
    void handleG03(const NCCommand &cmd);

// 处理 G40 指令，取消刀具半径补偿
    void handleG40(const NCCommand &cmd);

// 处理 G41 指令，左刀补
    void handleG41(const NCCommand &cmd);

// 处理 G42 指令，右刀补
    void handleG42(const NCCommand &cmd);

// 处理 G43 指令，启用刀具长度补偿
    void handleG43(const NCCommand &cmd);

// 处理 G44 指令，反向刀具长度补偿
    void handleG44(const NCCommand &cmd);

// 处理 G49 指令，取消刀具长度补偿
    void handleG49(const NCCommand &cmd);

///////////////////////////////////////////////////////////////
//M代码
    // 处理程序暂停指令
    void handleM00(const NCCommand &cmd);

    // 启动主轴旋转（顺时针）
    void handleM03(const NCCommand &cmd);

    // 启动主轴旋转（逆时针）
    void handleM04(const NCCommand &cmd);

    // 停止主轴旋转
    void handleM05(const NCCommand &cmd);

    // 程序结束并返回到开头
    void handleM30(const NCCommand &cmd);

    // 切换刀具指令（通常用于更换刀具）
    void handleM06(const NCCommand &cmd);










};



#endif //CNC_SIMULATION_NCMAIN_H
